package com.zksk.admin.service.org.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksk.admin.domain.agreement.vo.AgreementVo;
import com.zksk.admin.domain.org.dto.SignDto;
import com.zksk.admin.domain.org.vo.OrgProductVo;
import com.zksk.admin.service.org.OrgProductService;
import com.zksk.common.core.constant.OrgConstants;
import com.zksk.common.core.exception.ServiceException;
import com.zksk.common.security.utils.SecurityUtils;
import com.zksk.mbg.admin.domain.*;
import com.zksk.mbg.admin.mapper.*;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrgProductServiceImpl extends ServiceImpl<OrgProductMapper,OrgProduct> implements OrgProductService {

    @Autowired
    private ProductEnumMapper enumMapper;

    @Autowired
    private OrgProductMapper orgProductMapper;

    @Autowired
    private RateMapper rateMapper;

    @Autowired
    private RRateOrgProdMapper rRateOrgProdMapper;

    @Autowired
    private ROrgProdFieldMapper rOrgProdFieldMapper;

    @Autowired
    private AgreementMapper agreementMapper;

    @Autowired
    private RAgreementOrgProdMapper rAgreementOrgProdMapper;

    @Autowired
    private FieldSelectMapper fieldSelectMapper;


    @Override
    public OrgProductVo selectOrgProductVo(Long orgProductId) {
        OrgProductVo vo = new OrgProductVo();

        OrgProduct orgProduct = orgProductMapper.selectById(orgProductId);
        if (orgProduct == null){
            return null;
        }
        vo.setOrgProduct(orgProduct);

        // 协议
        List<RAgreementOrgProd> rAgreementOrgProds = rAgreementOrgProdMapper.selectList(
                new QueryWrapper<RAgreementOrgProd>()
                .eq(RAgreementOrgProd.ORG_PROD_ID, orgProductId)
                .eq(RAgreementOrgProd.ACTIVE,OrgConstants.ACTIVE_AV));

        List<Long> agreementIdsCollect = rAgreementOrgProds
                .stream()
                .map(RAgreementOrgProd::getAgreementId)
                .collect(Collectors.toList());

        if (!agreementIdsCollect.isEmpty()) {
            List<Agreement> agreements = agreementMapper.selectBatchIds(agreementIdsCollect);
            // 签章位置json
            List<AgreementVo> agreementVoList = Optional.ofNullable(agreements)
                    .orElseGet(Collections::emptyList)
                    .stream().map(item -> {
                        AgreementVo agreementVo = new AgreementVo();
                        BeanUtils.copyProperties(item, agreementVo);
                        if (item.getSignInfo() != null) {
                            List<SignDto> signDtos = JSONObject.parseArray(item.getSignInfo(), SignDto.class);
                            agreementVo.setSignDtos(signDtos);
                        }
                        return agreementVo;
                    }).collect(Collectors.toList());
            vo.setAgreementVos(agreementVoList);
        }

        // 标段-字段  关系表字段
        List<ROrgProdField> rOrgProdFields = rOrgProdFieldMapper.selectList(
                new QueryWrapper<ROrgProdField>()
                .eq(ROrgProdField.ORG_PRODUCT_ID,orgProductId) // 查询出关联的字段
                .eq(ROrgProdField.ACTIVE,OrgConstants.ACTIVE_AV)); // 生效

        List<Long> fieldIds = rOrgProdFields
                .stream()
                .map(ROrgProdField::getFieldId)
                .collect(Collectors.toList());

        if (!fieldIds.isEmpty()) {
            List<FieldSelect> fieldSelects = fieldSelectMapper.selectBatchIds(fieldIds);
            // 标段
            List<FieldSelect> sectionFieldsCollect = fieldSelects
                    .stream()
                    .filter(p -> p.getFieldType().equals(OrgConstants.ORG_TABLE_TYPE_SECTION))
                    .collect(Collectors.toList());

            List<FieldSelect> companyFieldsCollect = fieldSelects
                    .stream()
                    .filter(p -> p.getFieldType().equals(OrgConstants.ORG_TABLE_TYPE_COMPANY))
                    .collect(Collectors.toList());

            vo.setSectionFieldList(sectionFieldsCollect);
            vo.setCompanyFieldList(companyFieldsCollect);
        }

//        if (rOrgProdFields != null && rOrgProdFields.size() > 0) {
//
//            List<FieldSelect> fieldSelects = fieldSelectMapper.selectBatchIds(
//                    rOrgProdFields.stream()
//                            .map(ROrgProdField::getFieldId)
//                            .collect(Collectors.toList()));
//            // 标段
//            List<FieldSelect> sectionFieldsCollect = fieldSelects.stream()
//                    .filter(p -> p.getFeildType().equals(OrgConstants.ORG_TABLE_TYPE_SECTION))
//                    .collect(Collectors.toList());
//
//            List<FieldSelect> companyFieldsCollect = fieldSelects.stream()
//                    .filter(p -> p.getFeildType().equals(OrgConstants.ORG_TABLE_TYPE_COMPANY))
//                    .collect(Collectors.toList());
//            vo.setSectionFieldList(sectionFieldsCollect);
//            vo.setCompanyFieldList(companyFieldsCollect);
//        }

        // 机构产品对应的费率关系列表
        List<RRateOrgProd> rRateOrgProds = rRateOrgProdMapper.selectList(
                new QueryWrapper<RRateOrgProd>()
                .eq(RRateOrgProd.ORG_PROD_ID, orgProductId)
                .eq(RRateOrgProd.ACTIVE, OrgConstants.ACTIVE_AV));

        List<Long> rateIds = Optional.ofNullable(rRateOrgProds)
                .orElseGet(Collections::emptyList)
                .stream()
                .map(RRateOrgProd::getRateId)
                .collect(Collectors.toList());

        // 费率列表
        if (!rateIds.isEmpty()) {
            vo.setRateList(rateMapper.selectBatchIds(rateIds));
        }

        // 支付方式
        String[] payments = new String[]{"1","2"};// TODO
        vo.setPaymentList(Arrays.asList(payments));
        return vo;
    }

    @Override
    @Transactional
    public OrgProduct insertOrgProduct(OrgProductVo vo) {
        String OPERATOR_NAME = SecurityUtils.getUsername();
        // 1、新增产品
        OrgProduct orgProduct = vo.getOrgProduct();

        ProductEnum argEnum = new ProductEnum();
        argEnum.setId(orgProduct.getEnumProdId());

        ProductEnum productEnum = enumMapper.selectById(orgProduct.getEnumProdId());
        orgProduct.setEnumProdName(productEnum.getName()); // 插入产品枚举名称
        orgProduct.setCreateBy(OPERATOR_NAME);

        orgProductMapper.insert(orgProduct);

        Long insertOrgProductId = orgProduct.getId();
        // 2、新增费率表记录
        // 批量进行插入操作
        Optional.ofNullable(vo.getRateList())
            .orElseGet(Collections::emptyList)
            .forEach(item -> {
                item.setCreateBy(OPERATOR_NAME);
                rateMapper.insert(item);
                // 2-1、 构建费率与机构产品的关联关系 并插入库中
                RRateOrgProd rRateOrgProd = new RRateOrgProd();
                rRateOrgProd.setRateId(item.getId());
                rRateOrgProd.setOrgProdId(insertOrgProductId);
                rRateOrgProd.setActive(OrgConstants.ACTIVE_AV);
                rRateOrgProdMapper.insert(rRateOrgProd);
            });

        // 3、新增机构产品与字段（标段）的记录
        List<FieldSelect> sectionFieldList = vo.getSectionFieldList();
        Optional.ofNullable(sectionFieldList)
            .orElseGet(Collections::emptyList)
            .forEach(item -> {
                ROrgProdField rOrgProdField = new ROrgProdField();
                rOrgProdField.setTableType(OrgConstants.ORG_TABLE_TYPE_SECTION);
                rOrgProdField.setFieldId(item.getFieldId());
                rOrgProdField.setOrgProductId(insertOrgProductId);
                rOrgProdField.setActive(OrgConstants.ACTIVE_AV);
                rOrgProdFieldMapper.insert(rOrgProdField);
            });

        // 4、新增机构产品与字段（企业信息）的记录
        List<FieldSelect> companyFieldList = vo.getCompanyFieldList();
        Optional.ofNullable(companyFieldList)
            .orElseGet(Collections::emptyList)
            .forEach(item -> {
                ROrgProdField rOrgProdField = new ROrgProdField();
                rOrgProdField.setTableType(OrgConstants.ORG_TABLE_TYPE_COMPANY);
                rOrgProdField.setFieldId(item.getFieldId());
                rOrgProdField.setOrgProductId(insertOrgProductId);
                rOrgProdField.setActive(OrgConstants.ACTIVE_AV);
                rOrgProdFieldMapper.insert(rOrgProdField);
            });

        // 5、新增协议
        List<AgreementVo> agreements = vo.getAgreementVos();
        Optional.ofNullable(agreements)
            .orElseGet(Collections::emptyList)
            .forEach(
                item -> {
                    item.setSignInfo(null); // 首先清理之前的字段值
                    // 新增协议签章位置
                    List<SignDto> signDtoList = item.getSignDtos();

                    if(signDtoList != null && signDtoList.size() > 0){
                        String signsDtoListStr = JSONObject.toJSONString(signDtoList);
                        item.setSignInfo(signsDtoListStr); // 插入协议的签章位置
                    }

                    item.setCreateBy(OPERATOR_NAME); // 创建人
                    agreementMapper.insert(item);

                    Long agreementId = item.getId();
                    // 5、新增协议与机构产品的关联关系
                    RAgreementOrgProd agreementOrgProd = new RAgreementOrgProd();
                    agreementOrgProd.setAgreementId(agreementId);
                    agreementOrgProd.setOrgProdId(insertOrgProductId);
                    agreementOrgProd.setActive(OrgConstants.ACTIVE_AV);
                    rAgreementOrgProdMapper.insert(agreementOrgProd);
                });
        return orgProduct;
    }

    @Override
    @Transactional
    public OrgProduct updateOrgProduct(OrgProductVo vo) {
        String OPERATOR_NAME = SecurityUtils.getUsername();
        // 1、更新机构产品信息
        OrgProduct orgProduct = vo.getOrgProduct();
        Long orgProductId = orgProduct.getId(); // 机构产品id

        // 机构产品id已经传入 进行更新机构产品信息
        orgProduct.setUpdateBy(OPERATOR_NAME);
        orgProductMapper.updateById(orgProduct); // 更新机构产品信息

        ProductEnum argEnum = new ProductEnum();
        argEnum.setId(orgProduct.getEnumProdId());

        ProductEnum productEnum = enumMapper.selectById(orgProduct.getEnumProdId());

        orgProduct.setEnumProdName(productEnum.getName()); // 插入产品枚举名称
        // 2-1、更新机构产品 费率
        // 传入为null 默认之前的关联关系失效 并清楚关联的费率记录
        List<Rate> rates = vo.getRateList();
        // 查询关联的费率记录
        QueryWrapper<RRateOrgProd> queryWrapper = new QueryWrapper<RRateOrgProd>()
                .eq(RRateOrgProd.ORG_PROD_ID, orgProductId);

        List<RRateOrgProd> rRateOrgProds = rRateOrgProdMapper.selectList(queryWrapper);
        List<Long> ratesCollect =
                Optional.ofNullable(rRateOrgProds)
                .orElseGet(Collections::emptyList)
                .stream()
                .map(RRateOrgProd::getRateId)
                .collect(Collectors.toList());

        // 该产品与费率有过绑定  对其进行删除
        rateMapper.deleteBatchIds(ratesCollect);

        // 对费率与产品的关系进行失效处理
        RRateOrgProd rRateOrgProd = new RRateOrgProd();
        rRateOrgProd.setActive(OrgConstants.ACTIVE_UN_AV); // 关系失效标识 1

        rRateOrgProdMapper.update(rRateOrgProd,
                new UpdateWrapper<RRateOrgProd>()
                        .eq(RRateOrgProd.ORG_PROD_ID, orgProductId) // 机构产品id对应 进行批量更新关系失效
        );   // 更新机构产品与费率的关系

        // 2-2、直接进行新增 费率&&产品与费率关系
        Optional.ofNullable(rates)
                .orElseGet(Collections::emptyList)
                .forEach(item->{
                    item.setCreateBy(OPERATOR_NAME);
                    rateMapper.insert(item);
                    // 2-1、 构建费率与机构产品的关联关系 并插入库中
                    RRateOrgProd insertRROP = new RRateOrgProd();
                    insertRROP.setRateId(item.getId());
                    insertRROP.setOrgProdId(orgProductId);
                    insertRROP.setActive(OrgConstants.ACTIVE_AV);
                    rRateOrgProdMapper.insert(insertRROP);
                });

        // 3、更新机构产品与字段（标段）的记录&&机构产品与字段（企业）的记录

        // 3-1 删除机构产品与字段（标段）的关系 && 机构产品与字段（企业）的关系
        ROrgProdField rOrgProdField = new ROrgProdField();
        rOrgProdField.setActive(OrgConstants.ACTIVE_UN_AV); // 失效状态
        rOrgProdFieldMapper.update(rOrgProdField,
                new UpdateWrapper<ROrgProdField>()
                .eq(ROrgProdField.ORG_PRODUCT_ID, orgProductId)); // 对该机构产品对应的字段进行批量失效

        // 新增关系
        List<FieldSelect> sectionFieldList = vo.getSectionFieldList();
        List<FieldSelect> companyFieldList = vo.getCompanyFieldList();
        // 3-2 新增机构与字段（标段）的关系
        List<ROrgProdField> rOrgProdFields = new ArrayList<>();

        for (FieldSelect fieldSelect : sectionFieldList) {
            ROrgProdField insert = new ROrgProdField();
            insert.setFieldId(fieldSelect.getFieldId());
            insert.setTableType(OrgConstants.ORG_TABLE_TYPE_SECTION);
            rOrgProdFields.add(insert);
        }
        // 3-3 新增机构与字段（企业）的关系
        for (FieldSelect fieldSelect : companyFieldList) {
            ROrgProdField insert = new ROrgProdField();
            insert.setFieldId(fieldSelect.getFieldId());
            insert.setTableType(OrgConstants.ORG_TABLE_TYPE_COMPANY);
            rOrgProdFields.add(insert);
        }
        Optional.of(rOrgProdFields)
                .orElseGet(Collections::emptyList)
                // 3-4 批量插入
                .forEach(item->{
                item.setActive(OrgConstants.ACTIVE_AV); // 生效关系
                item.setOrgProductId(orgProductId);
                item.setActive(OrgConstants.ACTIVE_AV);
                rOrgProdFieldMapper.insert(item);  // 批量插入机构&企业字段关系
            });

        // 5、更新协议&机构产品与协议关系
        // 5-1 先删除 机构产品与协议关系
        QueryWrapper<RAgreementOrgProd> wrapper = new QueryWrapper<>();
        wrapper.eq(RAgreementOrgProd.ORG_PROD_ID,orgProductId);

        List<RAgreementOrgProd> rAgreementOrgProds = rAgreementOrgProdMapper.selectList(wrapper);// 机构产品id
        List<Long> deleteIdsCollect = rAgreementOrgProds
                .stream()
                .map(RAgreementOrgProd::getAgreementId)
                .collect(Collectors.toList());

        agreementMapper.deleteBatchIds(deleteIdsCollect);       // 删除协议

        // 删除机构产品与协议关系  更新关系
        rAgreementOrgProdMapper.update(
                new RAgreementOrgProd()
                        .setActive(OrgConstants.ACTIVE_UN_AV), wrapper); // 关系进行更新 -> 失效

        // 5-2 新增协议及其产品与协议关系
        List<AgreementVo> agreements = vo.getAgreementVos();
        Optional.of(agreements)
            .orElseGet(Collections::emptyList)
            .forEach(
                item -> {
                    item.setSignInfo(null);
                    // 新增协议签章位置
                    List<SignDto> signDtoList = item.getSignDtos();
                    if(signDtoList != null && signDtoList.size() > 0){
                        String signsDtoListStr = JSONObject.toJSONString(signDtoList);
                        item.setSignInfo(signsDtoListStr); // 插入协议的签章位置
                    }
                    item.setUpdateBy(OPERATOR_NAME); // 创建人
                    agreementMapper.insert(item);
                    Long agreementId = item.getId();
                    // 新增协议与机构产品的关联关系
                    RAgreementOrgProd agreementOrgProd = new RAgreementOrgProd();
                    agreementOrgProd.setAgreementId(agreementId);
                    agreementOrgProd.setOrgProdId(orgProductId);
                    agreementOrgProd.setActive(OrgConstants.ACTIVE_AV);
                    rAgreementOrgProdMapper.insert(agreementOrgProd);
                });
        return orgProduct;
    }

    @Override
    @SneakyThrows
    public boolean deleteOrgProductRelation(List<Long> ids) {

        List<RRateOrgProd> rRateOrgProds = rRateOrgProdMapper.selectList(
                new QueryWrapper<RRateOrgProd>()
                .in(RRateOrgProd.ORG_PROD_ID, ids));
        if (rRateOrgProds!=null && rRateOrgProds.size() > 0) {
            // 删除费率
            List<Long> rateIds = rRateOrgProds.stream().map(RRateOrgProd::getRateId).collect(Collectors.toList());
            rateMapper.deleteBatchIds(rateIds);
        }

        // 删除机构产品与费率 生效字段
        rRateOrgProdMapper.delete(new QueryWrapper<RRateOrgProd>().in(RRateOrgProd.ORG_PROD_ID, ids));

       // 更新机构产品与字段 生效字段
        rOrgProdFieldMapper.delete(new QueryWrapper<ROrgProdField>().in(ROrgProdField.ORG_PRODUCT_ID, ids));

        // 删除协议列表
        QueryWrapper<RAgreementOrgProd> queryWrapper = new QueryWrapper<RAgreementOrgProd>().in(RAgreementOrgProd.ORG_PROD_ID, ids);

        List<RAgreementOrgProd> rAgreementOrgProds = rAgreementOrgProdMapper.selectList(queryWrapper);
        List<Long> agreementIds = rAgreementOrgProds
                .stream()
                .map(RAgreementOrgProd::getAgreementId)
                .collect(Collectors.toList());
        agreementMapper.deleteBatchIds(agreementIds);

        rAgreementOrgProdMapper.delete(queryWrapper);

        // 删除机构产品与支付
        return true;
    }

    @Override
    public OrgProduct selectOrgByOrgId(Long orgId) {
        if(orgId == null|orgId == 0){
            throw new ServiceException("机构id不能为空");
        }
        OrgProduct orgProduct = orgProductMapper.selectByOrgId(orgId);
        return orgProduct;
    }
}